home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
archiver
/
zoo21src.zoo
/
vms.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-07-24
|
11KB
|
387 lines
#ifndef LINT
/* derived from: @(#) vms.c 2.2 88/01/09 03:47:52 */
static char vmsid[]="$Source$\n\
$Id$";
#endif /* LINT */
/* Support routines for VAX/VMS. */
#include <stat.h>
#include <time.h>
/* our own version of NULL; avoid any interaction with system defn.
but don't require inclusion of stdio.h */
#define NILPTR 0
/* Function isuadir() returns 1 if the supplied filename is a directory,
else it returns 0.
*/
int isuadir (file)
char *file;
{
struct stat buf; /* buffer to hold file information */
if (stat (file, &buf) == -1) {
return (0); /* inaccessible -- assume not dir */
} else {
if (buf.st_mode & S_IFDIR)
return (1);
else
return (0);
}
}
/****************
Function fixfname() converts the supplied filename to a syntax
legal for the host system. It is used during extraction. We
allow a maximum of one dot in the filename, and it must not
be at the beginning. We also truncate the number of charac-
ters preceding and following the dot to at most 39.
*/
char *strchr();
char *fixfname(fname)
char *fname;
{
char *p;
char *dotpos;
static char legal[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_.0123456789";
/* convert all characters to legal characters */
for (p = fname; *p != '\0'; p++)
if (strchr (legal, *p) == 0) {
if (*p == '-' || *p == ' ')
*p = '_';
else
*p = legal [ *p % 26 ];
}
/* first char can't be dot */
if (*fname == '.')
*fname = 'X';
/* find embedded dot if any */
dotpos = strchr (fname, '.');
if (dotpos != NILPTR) {
for (p = dotpos+1; *p != '\0'; p++) /* remove 2nd dot onwards */
if (*p == '.')
*p = '_';
if (dotpos - fname + 1 > 39) { /* more than 39 before dot not allowed */
char *q;
p = fname + 39;
q = dotpos;
while (*p++ = *q++) /* the notational convenience is considerable */
;
dotpos = strchr (fname, '.');
}
if (strlen (dotpos + 1) > 39) /* more than 39 after dot not allowed */
*(dotpos + 39 + 1) = '\0';
} else
*(fname + 39) = '\0'; /* no dots, just truncate to 39 characters */
return (fname);
}
/*
Function gettz(), returns the offset from GMT in seconds of the
local time, taking into account daylight savings time -- or it
would, if VAX/VMS knew about timezones! It's just a no-op.
*/
long gettz()
{
return 0L;
}
struct tm *localtime();
/*****************
Function gettime() gets the date and time of the file handle supplied.
Date and time is in MSDOS format. This function duplicated from nixtime.i.
*/
int gettime (file, date, time)
ZOOFILE file;
unsigned *date, *time;
{
struct stat buf; /* buffer to hold file information */
struct tm *tm; /* will hold year/month/day etc. */
int handle;
handle = fileno(file);
if (fstat (handle, &buf) == -1) {
prterror ('w', "Could not get file time\n");
*date = *time = 0;
} else {
tm = localtime (&buf.st_mtime); /* get info about file mod time */
*date = tm->tm_mday + ((tm->tm_mon + 1) << 5) +
((tm->tm_year - 80) << 9);
*time = tm->tm_sec / 2 + (tm->tm_min << 5) +
(tm->tm_hour << 11);
}
}
/*
Function unlink() will delete a file using the VMS C delete()
function.
*/
int unlink (fname)
char *fname;
{
return (delete (fname));
}
/*
Function zooexit() receives attempts at exit. It always invokes
exit() with status=1.
*/
void zooexit (status)
int status;
{
exit (1);
}
/*
Function rename() renames a file.
Thanks to Owen Anthony (was <anthony@bsu-cs.bsu.edu> at one time).
*/
#include <descrip.h>
#ifdef NEED_VMS_RENAME /* if not using VMS 4.6 library rename() */
int rename (old_name, new_name)
char *old_name;
char *new_name;
{
int status;
struct dsc$descriptor_s file1, file2;
file1.dsc$w_length = strlen (old_name); /* descriptor for old name */
file1.dsc$a_pointer = old_name;
file1.dsc$b_class = DSC$K_CLASS_S;
file1.dsc$b_dtype = DSC$K_DTYPE_T;
file2.dsc$w_length = strlen (new_name); /* descriptor for new name */
file2.dsc$a_pointer = new_name;
file2.dsc$b_class = DSC$K_CLASS_S;
file2.dsc$b_dtype = DSC$K_DTYPE_T;
status = LIB$RENAME_FILE (&file1, &file2);
return ((status & ~1) == 1);
}
#endif /* VMS_RENAME */
/*
Function specfname() modifies filenames before they are stored
in an archive. Currently we remove any trailing version field,
and then any trailing dot.
*/
char *specfname (fname)
char *fname;
{
char *p;
p = strchr (fname, ';');
if (p != NILPTR)
*p = '\0';
if (*fname != '\0') {
p = fname + strlen (fname) - 1; /* point to last char */
if (*p == '.') /* remove any trailing dot */
*p = '\0';
}
return (fname);
}
/*
Function specdir() modifies directory names before they are stored
in an archive. We remove any leading device name or logical
name and and the [ and ] that bracket any directory name.
Then we change any dots in the directory name to slashes.
*/
#if 0
/* test stub that just truncates dir to null string */
char *specdir (fname) char *fname;
{ *fname = '\0'; return (fname); }
#else
char *specdir (fname)
char *fname;
{
char *p;
char tmpstr[LFNAMESIZE];
p = strchr (fname, ':'); /* remove chars upto and including : */
if (p != NILPTR) {
strcpy (tmpstr, p+1);
strcpy (fname, tmpstr);
}
p = strchr (fname, '['); /* remove chars upto and including [ */
if (p != NILPTR) {
strcpy (tmpstr, p+1);
strcpy (fname, tmpstr);
}
p = strchr (fname, ']'); /* truncate at ] */
if (p != NILPTR) {
if (*(p+1) != '\0')
prterror ('w', "Trailing garbage in directory name\n");
*p = '\0';
}
for (p = fname; *p != '\0'; p++) /* change dots to slashes */
if (*p == '.')
*p = '/';
/* make sure there is a leading slash -- just a hack for now */
if (*fname != '/') {
strcpy (tmpstr, fname);
strcpy (fname, "/");
strcat (fname, tmpstr);
}
#ifdef DEBUG
printf ("dir name transformed to \"%s\"\n", fname);
#endif
}
#endif
#define FMAX 3 /* Number of different filename patterns */
char *nextfile (what, filespec, fileset)
int what; /* whether to initialize or match */
register char *filespec; /* filespec to match if initializing */
register int fileset; /* which set of files */
{
int status;
char *p; /* temp ptr */
struct dsc$descriptor_s d_fwild, d_ffound;
static int first_time [FMAX+1];
static char saved_fspec [FMAX+1][PATHSIZE]; /* our own copy of filespec */
static char found_fspec [FMAX+1][PATHSIZE]; /* matched filename */
static unsigned long context [FMAX+1]; /* needed by VMS */
if (what == 0) {
strcpy (saved_fspec[fileset], filespec); /* save the filespec */
first_time[fileset] = 1;
return (0);
}
/* Reach here if what is not 0, so it must be 1 */
/* Create a descriptor for the wildcarded filespec */
d_fwild.dsc$w_length = strlen (saved_fspec[fileset]);
d_fwild.dsc$a_pointer = saved_fspec[fileset];
d_fwild.dsc$b_class = DSC$K_CLASS_S;
d_fwild.dsc$b_dtype = DSC$K_DTYPE_T;
d_ffound.dsc$w_length = sizeof (found_fspec[fileset]);
d_ffound.dsc$a_pointer = found_fspec[fileset];
d_ffound.dsc$b_class = DSC$K_CLASS_S;
d_ffound.dsc$b_dtype = DSC$K_DTYPE_T;
if (first_time[fileset]) {
first_time[fileset] = 0;
context[fileset] = 0L; /* tell VMS this is first search */
}
status = LIB$FIND_FILE (&d_fwild, &d_ffound, &context[fileset]);
status = status & 1; /* use only lowest bit */
if (status == 0) {
LIB$FIND_FILE_END (&context[fileset]);
return ((c